package com.gjzhao.fmmall.controller;

import cn.hutool.json.JSONUtil;
import com.gjzhao.fmmall.entity.ShoppingCart;
import com.gjzhao.fmmall.entity.Users;
import com.gjzhao.fmmall.service.ShoppingCartService;
import com.gjzhao.fmmall.vo.ResponseResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: 购物车 Controller
 * @Author: gjzhao
 * @Date Created in 2021-12-31 11:00 下午
 */
@CrossOrigin
@RestController
@RequestMapping("/shoppingCart")
@Api(value = "提供购物车相关数据的接口", tags = "购物车管理")
public class ShoppingCartController extends BaseController{

    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 接口作用：根据用户id，查询购物车列表
     * 业务流程分析：
     *   - 1.用户点击购物车
     *   - 2.调用该接口，需要携带token(token一般放在请求头中进行携带),后台进行验证当前登录是否有效
     *   - 3.查询该用户下购物车的信息(购物车基本信息/商品名字/商品主图/sku原价.销售价)
     *   - 4.前端按照一个商品一栏展示商品信息
     * @param userId 用户id
     * @param token  token
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value = "购物车列表查询")
    @ApiImplicitParam(dataType = "int", name = "userId", value = "用户ID", required = true)
    public ResponseResultVO list(@RequestHeader("token") String token,
                                 @RequestParam("userId") Integer userId) {
        //当前登录用户信息可以不从前端传过来，直接从redis中获取
        String userStr = stringRedisTemplate.boundValueOps(token).get();
        Users user = JSONUtil.toBean(userStr, Users.class);
        logger.info("---当前登录用户:{}-----",user.getUsername());
        ResponseResultVO resultVO = shoppingCartService.listShoppingCartsByUserId(userId);
        return resultVO;
    }

    /**
     * 接口作用：添加商品到购物车
     *
     * 如果当前用户登录有效，进行添加购物车
     *      - 1.在商品详情页面，选择商品套餐，记录商品信息
     *      - 2.调用该接口，添加购物车
     *
     * (
     * 业界处理未登录情况添加购物车的方案有3种：
     *      - 1.未登录情况下想要访问商品，跳转到登录页，必须先进行登录，再能添加商品
     *      - 2.未登录情况下可以浏览器商品，但是当进行添加时，发现没有登录，弹出登录框进行登录，然后才能添加购物车操作
     *      - 3.未登录情况下可以浏览商品，添加购物车时，先跳转到登录页面，登录完成后，再回到购物车页面
     * )
     *
     * 针对解决方案3的业务流程分析：
     * - 1.用户在商品详情页面点击"加入购物车"，
     * - 2.后台验证token，发现未登录，响应未登录的验证码
     * - 3.在前端页面，携带商品信息(商品id+套餐skuId+商品数量)，到登录页面进行登录
     * - 4.登录完成后，如果登录成功
     *      - 4.1 校验当前是否有returnUrl，没有则跳转到首页，
     *      - 4.2 有的话，携带参数跳转到购物车详情页面
     * - 5.在购物车详情页面,可以从cookie获取到用户信息进行显示，同时拿到路径上的参数，进行购物车添加
     * - 6.使用layer组件进行添加成功与否的提示
     *
     * 注意点：登录token校验的验证码值与业务操作的验证码要进行区分，这样在前端在知道当前是否已登录
     *
     * @param shoppingCart 需要添加的购物车信息
     * @param token        token 用于校验当前登录
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "购物车添加商品(登录状态)")
    public ResponseResultVO add(@RequestBody ShoppingCart shoppingCart,
                                @RequestHeader("token") String token) {

        ResponseResultVO resultVO = shoppingCartService.addShoppingCart(shoppingCart);
        return resultVO;
    }

    /**
     * 更新操作使用 @PutMapping，路径传参使用{..}配合 @PathVariable 注解一起使用
     * 接口作用：根据购物车id，修改购物车商品的数量
     * 业务流程分析：
     * - 1.为购物车每个商品数量旁边的 +与- 按钮添加点击事件，事件触发时，修改商品数量，发送ajax请求，修改购物车商品的数量
     * - 2.后端校验token
     * - 3.携带购物车id与需要修改的商品数量，更新购物车表信息即可
     *
     * @param token         token
     * @param cartId        购物车id
     * @param catProductNum 商品数量
     * @return
     */
    @PutMapping("/update/{cartId}/{catProductNum}")
    @ApiOperation(value = "购物车修改商品数量")
    public ResponseResultVO update(@RequestHeader("token") String token,
                                   @PathVariable String cartId,
                                   @PathVariable String catProductNum) {

        ResponseResultVO resultVO = shoppingCartService.updateShoppingCartNum(cartId, catProductNum);
        return resultVO;
    }

    /**
     * 查询一组购物车信息
     *  - 1.从购物车页面到结算页时，需要展示所有添加到购物车的商品信息
     *  - 2.携带一组购物车id，通过字符串拼接为一个参数，在购物车表进行查询
     * @param token
     * @param cardIds
     * @return
     */
    @GetMapping("/listByCardIds")
    @ApiOperation(value = "查询购物车集合信息(sql方式实现)")
    @ApiImplicitParam(dataType = "string", name = "cardIds", value = "购物车id集合,字符串拼接", required = true)
    public ResponseResultVO listShoppingCart(@RequestHeader("token") String token,
                                             @RequestParam("cardIds") String cardIds) {

        ResponseResultVO resultVO = shoppingCartService.listShoppingCartByCartIds(cardIds);
        return resultVO;
    }

    @GetMapping("/listByCardIdsByTkMapper")
    @ApiOperation(value = "查询购物车集合信息(mapper方式实现)")
    @ApiImplicitParam(dataType = "string", name = "cardIds", value = "购物车id集合,字符串拼接", required = true)
    public ResponseResultVO listShoppingCartByTkMapper(@RequestHeader("token") String token,
                                                       @RequestParam("cardIds") String cardIds) {

        ResponseResultVO resultVO = shoppingCartService.listShoppingCartByCartIdsByMapper(cardIds);
        return resultVO;
    }

}
